package com.example.demo07cache.config;

import com.example.demo07cache.listener.RedisChannelListener;
import org.redisson.Redisson;
import org.redisson.api.RBloomFilter;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

@Configuration
public class MyRedisConfig {

    public static final String CLEAN_NO_STOCK_CACHE = "cleanNoStockCache";

    @Value("${spring.redis.password:}")
    private String password;

    @Autowired
    @Qualifier("redisConfig")
    private RedisStandaloneConfiguration redisConfig;

    @Bean
    public Redisson redisson() {
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://" + redisConfig.getHostName() + ":" + redisConfig.getPort())
                .setPassword(password)
                .setConnectionMinimumIdleSize(1)
                .setConnectionPoolSize(5)
                .setSubscriptionConnectionPoolSize(5)
                .setSubscriptionConnectionMinimumIdleSize(1)
                .setIdleConnectionTimeout(10000)
                .setDatabase(0);
        return (Redisson) Redisson.create(config);
    }

    @Bean
    public RBloomFilter<Object> rBloomFilter(Redisson redisson) {
        RBloomFilter<Object> bloomFilter = redisson.getBloomFilter("user:bit:map");
        bloomFilter.tryInit(10_0000L, 0.01);
        return bloomFilter;
    }


    // ************************* RedisKeyExpirationListener ************ start *************
    @Bean
    public KeyExpirationEventMessageListener keyExpirationEventMessageListener(RedisMessageListenerContainer redisMessageListenerContainer) {
        return new KeyExpirationEventMessageListener(redisMessageListenerContainer);
    }

    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory) {
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
        redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory);
        redisMessageListenerContainer.addMessageListener(messageListenerAdapter(), channelTopic());
        return redisMessageListenerContainer;
    }
    // ************************* RedisKeyExpirationListener ************* end ************


    // ************************* RedisChannelListener ************ start *************
    @Autowired
    private RedisChannelListener channelListener;

    /**
     * 监听一个 Channel
     */
    @Bean
    public ChannelTopic channelTopic() {
        return new ChannelTopic(CLEAN_NO_STOCK_CACHE);
    }

    @Bean
    public MessageListenerAdapter messageListenerAdapter() {
        return new MessageListenerAdapter(channelListener);
    }
    // ************************* RedisChannelListener ************* end ************
}
